package com.stockz.ui.swing.charting.display.indicator;

import java.awt.Graphics2D;
import java.util.List;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.stockz.core.model.Bar;
import com.stockz.core.util.ListUtil;
import com.stockz.core.util.BarUtil.BarValueType;
import com.stockz.ui.swing.charting.painter.indicator.LineIndicatorPainter;
import com.stockz.ui.swing.charting.util.MathUtil;
import com.stockz.ui.swing.charting.util.UIChartingConstant.OVERLAY;

@Component
@Scope("prototype")
public class SimpleMovingAverage extends AbstractDisplayableIndicatorConfiguration {

	public static class Configuration{
		private int span = 20;

		public int getSpan() {
			return span;
		}

		public void setSpan(int span) {
			this.span = span;
		}
	}

	public static double valueAll(double[] barValues){
		return MathUtil.avg(barValues);
	}
	
	public static double value(double[] barValues, int span){
		return MathUtil.avg(barValues, 0, span);
	}
	
	public static double[] values(double[] barValues, int span){
		if(barValues != null && span > 0 && barValues.length > span){
			double sum = 0;
			double[] values = new double[barValues.length];
			for(int i = barValues.length-1; i >=0; i--){
				if(barValues[i] == 0){
					continue;
				}
				if(i > barValues.length - span){
					values[i] = 0;
				}else if(i ==  barValues.length - span){
					values[i] = sum/span;
				}else{
					values[i] = sum/span;
					sum -= barValues[i+span];
				}
				sum += barValues[i];
			}
			return values;
		}
		return new double[0];
	}
	
	private Configuration configuration = new Configuration();
	
	@Override
	public void paint(Graphics2D g) {
		LineIndicatorPainter.paint(g, this);
	}
	
	@Override
	public Object getConfiguration() {
		return configuration;
	}
	
	@Override
	public String getDescription() {
		return getShortName()+","+configuration.getSpan()
		+","+getBarValueType();
	}
	
	@Override
	public OVERLAY getOverlay() {
		BarValueType barValueType = getBarValueType();
		if(BarValueType.VOLUME.equals(barValueType)){
			return OVERLAY.VOLUME;
		}else if(BarValueType.AVGTRADESIZE.equals(barValueType)
				|| BarValueType.TRADES.equals(barValueType)
				|| BarValueType.TURNOVER.equals(barValueType)
				|| BarValueType.SPREAD.equals(barValueType)){
			return OVERLAY.INDEPENDENT;
		}else{
			return OVERLAY.PRICE;
		}
	}

	@Override
	public boolean isOverlappable() {
		return true;
	}
	
	@Override
	public String getFullName() {
		return "Simple Moving Average";
	}

	@Override
	public String getShortName() {
		return "SMA";
	}

	@Override
	public void refreshValues() {
		List<Bar> barList = getStockChartPanel().getStockChartPanelState().getBarList();
		if(barList != null && barList.size() > configuration.getSpan()){
			double[] barValues = ListUtil.convert(barList, getBarValueType());
			setValues(values(barValues, configuration.getSpan()));
		}
	}
}